const fs = require('fs');
const path = require('path');
const { parse } = require('@vue/compiler-sfc');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generate = require('@babel/generator').default;

// 读取并解析 Vue 文件
const filePath = path.resolve(__dirname, 'App.vue');
const source = fs.readFileSync(filePath, 'utf8');
const { descriptor } = parse(source);

function memberExpressionToString(node) {
  if (!node) return '';

  // 处理基础情况：非 MemberExpression 节点（如标识符或字面量）
  if (node.type === 'Identifier') {
    return node.name;
  } else if (node.type === 'Literal') {
    return typeof node.value === 'string' ? `'${node.value}'` : String(node.value);
  }

  // 处理计算属性（如 obj['key'] 或 obj[1 + 2]）
  if (node.type === 'MemberExpression') {
    const objectStr = memberExpressionToString(node.object);
    const propertyStr = node.computed
      ? `[${memberExpressionToString(node.property)}]` // 计算属性用方括号
      : `.${node.property.name}`; // 非计算属性用点号

    return `${objectStr}${propertyStr}`;
  }

  // 处理其他情况（如函数调用、二元表达式等）
  return `[${node.type}]`; // 未知类型用占位符表示
}

// 提取并解析 <script> 内容
if (descriptor.script) {
  const scriptContent = descriptor.script.content;
  
  // 解析 JavaScript 代码为 AST（添加必要的插件）
  const scriptAst = parser.parse(scriptContent, {
    sourceType: 'module',
    plugins: [
      'objectRestSpread',
      'classProperties',
      'asyncGenerators', // 支持 async/await
      'optionalChaining' // 支持可选链操作符
    ]
  });
  
  // 存储所有符合条件的赋值语句
  const targetAssignments = [];
  
  // 遍历 AST，查找 methods 选项
  traverse(scriptAst, {
    ObjectProperty(path) {
      // 找到 methods 选项
      if (path.node.key.name === 'methods') {
        const methodsObj = path.node.value;
        
        // 遍历 methods 对象中的所有方法
        if (methodsObj.type === 'ObjectExpression') {
          console.log('找到 methods 对象，包含', methodsObj.properties.length, '个方法');
          
          methodsObj.properties.forEach(method => {
            // 获取方法的路径
            const methodPath = path.get('value').get('properties').find(
              p => p.node === method
            );
            
            // 处理不同类型的方法定义
            const isMethod = method.type === 'ObjectMethod';
            const isPropertyWithFunction = 
              method.type === 'ObjectProperty' && 
              (method.value.type === 'FunctionExpression' || 
               method.value.type === 'ArrowFunctionExpression');
               
            if (isMethod || isPropertyWithFunction) {
              console.log('正在分析方法:', method.key.name);
              methodPath.traverse({
                CallExpression(callPath) {
                  console.log('找到函数调用:', callPath.node.callee.name || '匿名函数');
                  
                  const { callee, arguments: args } = callPath.node;
                  
                  // 检查第三个参数是否为对象且包含 success/sucess 属性
                  if (
                    args.length >= 3 &&  // 修改为检查至少有3个参数
                    args[2].type === 'ObjectExpression'  // 检查第三个参数
                  ) {
                    const optionsObj = args[2];  // 获取第三个参数
                    
                    // 记录第一个参数（新增）
                    const firstArg = args[0];
                    const firstArgInfo = {
                      type: firstArg.type,
                      value: firstArg.type === 'StringLiteral' ? firstArg.value : '[复杂表达式]'
                    };
                    
                    if (firstArg.type === 'MemberExpression') {
                      firstArgInfo.value = memberExpressionToString(firstArg);
                      console.log(memberExpressionToString(firstArg), '------');
                    }
                    console.log('第一个参数:', firstArgInfo);

                    // 查找 success/sucess 回调
                    optionsObj.properties.forEach(prop => {
                      if (
                        (prop.key.name === 'success' || prop.key.name === 'sucess') &&
                        (prop.value.type === 'FunctionExpression' || prop.value.type === 'ArrowFunctionExpression')
                      ) {
                        console.log('找到 success/sucess 回调在:', callee.name);
                        
                        // 获取回调函数路径（注意这里修改为 arguments[2]）
                        const callbackPath = callPath.get('arguments')[2].get('properties').find(
                          p => p.node === prop
                        ).get('value');
                        
                        // 遍历回调函数体
                        callbackPath.traverse({
                          AssignmentExpression(assignPath) {
                            checkThatOParamsAssignment(assignPath, callee, prop, method, firstArgInfo.value);
                          }
                        });
                      }
                    });
                  }
                }
              });
            }
          });
        }
      }
    }
  });
  
  // 检查赋值语句是否为 that.oParams.bEnablePic = ...
  function checkThatOParamsAssignment(assignPath, callee, callbackProp, method, firstArgInfo) {
    const assignNode = assignPath.node;
    // 检查赋值左侧是否为 that.oParams.bEnablePic
    if (
      assignNode.left.type === 'MemberExpression' && // bEnablePic 属性
      assignNode.left.object.type === 'MemberExpression' && // oParams 对象
      assignNode.left.object.object.type === 'Identifier' && // that 变量
      assignNode.left.object.object.name === 'that' &&
      assignNode.left.object.property.type === 'Identifier' &&
      assignNode.left.object.property.name === 'oParams' &&
      assignNode.left.property.type === 'Identifier' &&
      assignNode.left.property.name === 'bEnablePic'
    ) {
      targetAssignments.push({
        methodName: method.key.name,
        functionName: callee.name || 'anonymous',
        line: assignNode.loc.start.line,
        column: assignNode.loc.start.column,
        code: generate(assignNode).code,
        isMisspelled: callbackProp.key.name === 'sucess',
        apiKey: firstArgInfo
      });
    }
  }
  
  // 打印结果
  console.log(`在 ${filePath} 中找到 ${targetAssignments.length} 个匹配的赋值语句:`);
  targetAssignments.forEach(({ methodName, functionName, line, column, code, isMisspelled, apiKey }, index) => {
    console.log(`\n${index + 1}. 在方法 ${methodName} 中:`);
    console.log(`   调用函数: ${functionName}`);
    console.log(`   位置: 第${line}行，第${column}列`);
    console.log(`   赋值语句: ${code}`);
    console.log(`   被执行函数的参数: ${apiKey}`);
    if (isMisspelled) console.log(`   ⚠️ 警告: 使用了错误的回调名称 "${callbackProp.key.name}"`);
  });
}